package com.blue.gateway.paycore.alipay.refund;

import com.alibaba.fastjson.JSON;
import com.blue.gateway.annotation.Channel;
import com.blue.gateway.common.Request;
import com.blue.gateway.common.request.RefundRequest;
import com.blue.gateway.common.response.RefundResponse;
import com.blue.gateway.config.AliConfig;
import com.blue.gateway.config.BaseChannelConfig;
import com.blue.gateway.paycore.alipay.AliMethodEnum;
import com.blue.gateway.dto.Result;
import com.blue.gateway.dto.ResultWrapper;
import com.blue.gateway.enums.PayChannelEnum;
import com.blue.gateway.enums.ServiceChannelEnum;
import com.blue.gateway.utils.DateUtil;
import com.blue.gateway.utils.WebUtil;
import com.blue.gateway.utils.http.HttpClientsUtil;
import com.blue.gateway.paycore.AbstractBaseChannelService;
import com.blue.gateway.paycore.alipay.AliPayConstants;
import com.blue.gateway.utils.sign.AliPaySignature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @author xiaoyiming
 * @date 2020/5/4 15:01
 * @depiction https://opendocs.alipay.com/apis/api_1/alipay.trade.fastpay.refund.query
 */
@Slf4j
@Channel(PayChannel = PayChannelEnum.ALIPAY, ServiceChannel = ServiceChannelEnum.REFUND_QUERY)
public class AliRefundQueryService extends AbstractBaseChannelService {
    @Autowired
    private AliConfig aliConfig;

    @Override
    public Result validate(Request request) {
        return null;
    }

    @Override
    public BaseChannelConfig getConfig(Request request) {
        return aliConfig;
    }

    @Override
    public String generateParams(Request request, BaseChannelConfig channelConfig) {
        RefundRequest refundRequest = (RefundRequest) request;
        AliConfig aliConfig = (AliConfig) channelConfig;
        //公共请求参数
        SortedMap<String, String> paramMap = new TreeMap<>();
        paramMap.put("app_id", aliConfig.getAppId());
        paramMap.put("method", AliMethodEnum.TRADE_REFUND_QUERY.getMethodName());
        paramMap.put("charset", AliPayConstants.CHARSET_UTF8);
        paramMap.put("sign_type", AliPayConstants.SIGN_TYPE_RSA2);
        paramMap.put("timestamp", DateUtil.formatDateYMDHMS(new Date()));
        paramMap.put("version", AliPayConstants.VERSION);

        //请求参数 biz_content
        SortedMap<String, String> contentMap = new TreeMap<>();
        contentMap.put("trade_no", refundRequest.getTradeNo());
        contentMap.put("out_trade_no", refundRequest.getOutTradeNo());
        if (StringUtils.isBlank(refundRequest.getOutRequestNo())) {
            contentMap.put("out_request_no", refundRequest.getOutTradeNo());
        } else {
            contentMap.put("out_request_no", refundRequest.getOutRequestNo());
        }

        paramMap.put("biz_content", JSON.toJSONString(contentMap));

        //参数加密
        String sign = AliPaySignature.sign(paramMap, aliConfig.getPrivateKey());
        paramMap.put("sign", sign);


        return AliPayConstants.GATEWAY_URL + WebUtil.getRequestUrl(paramMap);
    }

    @Override
    public String execute(String requestParams, BaseChannelConfig channelConfig) {
        String result = null;
        try {
            result = HttpClientsUtil.httpClientGet(requestParams);
        } catch (Exception e) {
            // do nothing
        }
        return result;
    }

    /**
     * 正常数据
     * {
     * "alipay_trade_fastpay_refund_query_response":{
     * "code":"10000",
     * "msg":"Success"
     * },
     * "sign":"mqHShFJX9fvkxS7N1BClahpPOrkMEzKuFOzwVstu7ZIMlod4zTOOhXDgCcYLNOdK4qoiOzMeGzLMb9jQVQ418aat2iwppB0TEBsGRSYI933om2BjQ9CZ9F0CecBeTKp9s1lG9ycqUiTdaHrWutS677GQ2RCs9M6pPx5xUYP9UMWYwaM6+DAVAh1AkuD7c5BqgZmPNSJlf6WC5VMI2vlXQgvzeihRIbd4wd+aSKBDyeAqIo4wQ54NlJjUU69cmcK9Kuw5q+F/XolN2oYPyRCKZoObme8NkqOxNxzRRTBuNn3umeXfoAYY8eOcMOT2ijcWiy2Yw3zjuCKtV8/DCSTDPw=="
     * }
     * 异常数据:
     * {
     * "alipay_trade_fastpay_refund_query_response":{
     * "code":"40004",
     * "msg":"Business Failed",
     * "sub_code":"ACQ.TRADE_NOT_EXIST",
     * "sub_msg":"交易不存在",
     * "out_trade_no":"27898754987981"
     * },
     * "sign":"cv/uH2jEPL2C1HpDl1jS8Sh0MFEHdC9jTnOyae/Qq8os3HywWUhBvaGMF0Ja7MStU7Xwe3RG4bSacybKU2sncXjs/kGzXsXW8v67kmbKMQCi8o73O8MLCJsNdNcZHG8KRfz8JBADOTyIxPce6/mmoWH5z/E1kszmWqP5gWu2VBQi7nrPXAzYZAWZXsHruDbaxpEs6oWmtcsuSy2DZSmBCzuYAz7/5hE3Zgd5YvCY5QQBVJbxqA3i3k1L/XXaat/nPPgwLCc5mdYTn3t+z5WHqTVyayR7cs6t3hX5dTxkayzNr9GVyGkoOmSGaKHt+JewqZN+GQvuE9P2AhOSNONLhg=="
     * }
     *
     * @param executeResult
     * @return
     */
    @Override
    public Result analysisResult(String executeResult) {
        RefundResponse refundResponse = new RefundResponse();
        Map resultMap = JSON.parseObject(executeResult);
        Map map = JSON.parseObject(String.valueOf(resultMap.get(AliMethodEnum.TRADE_REFUND_QUERY.getResponseName())));
        String code = String.valueOf(map.get("code"));
        if (AliPayConstants.SUCCESS_CODE.equals(code)) {
            refundResponse.setData(executeResult);
            refundResponse.setMsg(String.valueOf(map.get("msg")));
            return ResultWrapper.success(refundResponse);
        } else {
            refundResponse.setData(String.valueOf(map.get("sub_msg")));
            return ResultWrapper.fail(refundResponse);
        }
    }
}
